home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / apidev / ndr3.exe / VERODI.C < prev    next >
C/C++ Source or Header  |  1993-11-14  |  12KB  |  403 lines

  1. /*
  2.    VERODI.C  shows how to obtain the version numbers (etc)
  3.              from ODI components using ODI API calls.
  4.  
  5.    Author:  Tim Farley
  6.    Copyright 1993, Tim Farley, All Rights Reserved
  7. */
  8.  
  9. #include <stdlib.h>  /* for NULL */
  10. #include <string.h>  /* for strlen() */
  11. #include <dos.h>     /* for GETVECT() & MK_FP() */
  12.  
  13. #ifdef __TURBOC__
  14.    #define ASM asm
  15.    #define GETVECT getvect
  16. #else
  17.    /* assume Microsoft C if not Turbo/Borland C */
  18.    #define ASM _asm
  19.    #define GETVECT _dos_getvect
  20. #endif
  21.  
  22. /* some compilers don't have this */
  23. #ifndef MK_FP
  24.   #define MK_FP(seg, offset) (void far *)(((unsigned long)seg << 16) \
  25.       + (unsigned long)(unsigned)offset)
  26. #endif
  27.  
  28. /*
  29.    Some useful definitions
  30. */
  31. typedef void (far * FuncPtr)(void);
  32. typedef char far * DataPtr;
  33.  
  34. /*
  35.    Pointers to the LSL entry points
  36. */
  37. static FuncPtr LSLentry = NULL;
  38. static FuncPtr LSLProtocolAPI = NULL;
  39. static FuncPtr LSLGeneralAPI = NULL;
  40.  
  41.  
  42. /*
  43.    DetectLSL  detects if LSL is present and fills in
  44.               the API entry points above.
  45. */
  46. static int CallMultiplex( unsigned int funCode, FuncPtr * lslEntry, DataPtr * lslSig );
  47. static int IsEqual( char far * first, char far * second, int len );
  48.  
  49. static int DetectLSL( void )
  50. {
  51.    unsigned long int2Fvector;
  52.    int returnCode;
  53.    unsigned int multiplex;
  54.    static char lslSignature[] = "LINKSUP$";
  55.    int lslSigLength = strlen( lslSignature ) - 1;
  56.    char far * lslSigPtr;
  57.    /* Need to put these two in a struct to guarantee they are
  58.       next to each other in memory */
  59.    struct {
  60.       FuncPtr LSLAPI1;
  61.       FuncPtr LSLAPI2;
  62.    } apiStruct;
  63.  
  64.    /* if we've already been called, skip it */
  65.    if  ( NULL != LSLentry )
  66.       return ( 1 );
  67.  
  68.    /*
  69.       Make sure INT 2Fh is initialized.  This is only
  70.       technically necessary to support DOS 2.x.
  71.    */
  72.    int2Fvector = (unsigned long)GETVECT( 0x2F );
  73.    if  ( 0UL == int2Fvector )    /* No INT 2Fh handler? */
  74.       return ( 0 );              /* then no LSL!  */
  75.  
  76.    /*
  77.       Loop through the possible multiplex numbers, looking
  78.       for the LINKSUP$ signature string to be returned by
  79.       one of them.
  80.    */
  81.    for ( multiplex = 0xC0; multiplex <= 0xFF; multiplex++ ) {
  82.       returnCode = CallMultiplex( multiplex, &LSLentry, &lslSigPtr );
  83.       if ( ( 0xFF == returnCode ) && ( NULL != lslSigPtr ) ) {
  84.          if  ( !IsEqual( lslSignature, lslSigPtr, lslSigLength ) )
  85.             LSLentry = NULL;     /* make sure it stays NULL */
  86.          else {
  87.             ASM {
  88.                push  si             /* Save C registers */
  89.                mov   ax,ss
  90.                mov   es,ax
  91.                lea   si,apiStruct   /* ES:SI -> apiStruct */
  92.                mov   bx,2           /* Func 2: retrieve entry points */
  93.                call  LSLentry
  94.                pop   si             /* Restore C registers */
  95.             }
  96.             LSLProtocolAPI = apiStruct.LSLAPI1;
  97.             LSLGeneralAPI  = apiStruct.LSLAPI2;
  98.             break;                  /* break out of for loop! */
  99.          }  /* if signature found */
  100.       }  /* if multiplex call succeeded */
  101.    }  /* for each possible multiplex */
  102.  
  103.    return ( NULL != LSLentry );
  104. }  /* DetectLSL() */
  105.  
  106.  
  107. /*
  108.    CallMultiplex  calls INT 2Fh and returns the appropriate pointers.
  109. */
  110. static int CallMultiplex( unsigned int funCode, FuncPtr * lslEntry, DataPtr * lslSig )
  111. {
  112.    int returnCode, retES, retSI, retDX, retBX;
  113.  
  114.    ASM {
  115.       xor   si,si    /* Zero out all return registers */
  116.       mov   es,si
  117.       mov   bx,si
  118.       mov   dx,si
  119.       mov   ax,funCode
  120.       xchg  ah,al
  121.       int   2fh
  122.       xor   ah,ah
  123.       mov   returnCode,ax
  124.       mov   retES,es
  125.       mov   retSI,si
  126.       mov   retDX,dx
  127.       mov   retBX,bx
  128.    }
  129.  
  130.    *lslSig   = MK_FP( retES, retSI );
  131.    *lslEntry = (FuncPtr)MK_FP( retDX, retBX );
  132.  
  133.    return ( returnCode );
  134. }  /* CallMultiplex() */
  135.  
  136.  
  137. /*
  138.    IsEqual returns 1 if two strings are equal, zero otherwise.
  139.  
  140.    We could use strcmp(), but since we need to compare with
  141.    strings that reside in TSR's (like "LINKSUP$") then that
  142.    restricts us to a large memory model.  Rolling our own allows
  143.    this code to be compiled in any memory model.
  144. */
  145. static int IsEqual( char far * first, char far * second, int len )
  146. {
  147.    int returnCode;
  148.  
  149.    ASM {
  150.       push  ds          /* Save C's registers */
  151.       push  di
  152.       push  si
  153.       les   di,first
  154.       lds   si,second
  155.       mov   cx,len
  156.       cld
  157.       repe  cmpsb
  158.       pushf             /* put flags into AX */
  159.       pop   ax
  160.       pop   si          /* Restore C's registers */
  161.       pop   di
  162.       pop   ds
  163.       mov   returnCode,ax
  164.    }
  165.  
  166.    return ( returnCode & 0x0040 );  /* return state of ZERO flag */
  167. }  /* IsEqual() */
  168.  
  169.  
  170. /*
  171.    GetLSLVersion()  returns the LSL version number if present,
  172.                     0 if it is not loaded.
  173.  
  174.    To get the version number, we must obtain a pointer to the
  175.    LSL Configuration Table, by calling function 12 on the
  176.    LSL Protocol support API.  We can then retrieve information
  177.    from inside that struct.
  178. */
  179. typedef struct {
  180.    unsigned char  ConfigMajorVer;
  181.    unsigned char  ConfigMinorVer;
  182.    unsigned long  NumLSLReceiveBuffers;
  183.    unsigned long  ReceiveBufferSize;      /* not including ECB */
  184.    unsigned char  LSLMajorVersion;
  185.    unsigned char  LSLMinorVersion;
  186.    int            MaxBoardsNum;
  187.    int            MaxStacksNum;
  188.    char           reserved2[ 12 ];
  189. } LSLConfig;
  190.  
  191. int GetLSLVersion( int * maxBoards, int * maxStacks )
  192. {
  193.    int lslVer;
  194.    int retES, retSI;
  195.    LSLConfig far * lslConfPtr;
  196.  
  197.    if  ( !DetectLSL() )
  198.       return ( 0 );
  199.  
  200.    ASM {
  201.       push  si             /* save C registers */
  202.       xor   si,si          /* zero return values */
  203.       mov   es,si
  204.       mov   bx,0019h       /* Func 19: GetLSLConfiguration */
  205.       call  LSLProtocolAPI
  206.       mov   retES,es
  207.       mov   retSI,si
  208.       pop   si
  209.    }
  210.  
  211.    lslConfPtr = MK_FP( retES, retSI );    /* point to config struct */
  212.    if  ( NULL == lslConfPtr )
  213.       return ( 0 );
  214.  
  215.    /* Pack the version number into the return value */
  216.    lslVer = ( lslConfPtr->LSLMajorVersion << 8 ) |
  217.       lslConfPtr->LSLMinorVersion;
  218.  
  219.    /* return the maximum number of boards & stacks it can take */
  220.    *maxBoards = lslConfPtr->MaxBoardsNum;
  221.    *maxStacks = lslConfPtr->MaxStacksNum;
  222.  
  223.    return ( lslVer );
  224. }  /* GetLSLVersion() */
  225.  
  226.  
  227. /*
  228.    GetModuleConfig  is an internal routine used by GetMLIDConfig
  229.                     and GetProtocolConfig.
  230.  
  231.    Use one of the two #defines below as the value of funCode,
  232.    to choose whether you are looking for an MLID or a Protocol.
  233. */
  234. #define GET_MLID_CONTROL      (0x0012)
  235. #define GET_PROTOCOL_CONTROL  (0x0013)
  236.  
  237. /* return values */
  238. #define GMC_SUCCESS           (int)(0)
  239. #define GMC_NO_MORE_ITEMS     (int)(0x8003)  /* not found & none beyond */
  240. #define GMC_ITEM_NOT_PRESENT  (int)(0x8004)  /* not found, but might be more */
  241. FuncPtr ModuleAPI = NULL;
  242.  
  243. static int GetModuleConfig( int funCode, int whichOne, DataPtr * configTable )
  244. {
  245.    int retES, retSI, returnCode;
  246.  
  247.    if  ( !DetectLSL() )
  248.       return ( 0 );
  249.  
  250.    ASM {
  251.       push  si             /* save C's registers */
  252.       xor   si,si
  253.       mov   es,si          /* zero out return value */
  254.       mov   bx,funCode     /* func number 12 or 13 */
  255.       mov   ax,whichOne    /* board # or protocol # */
  256.       call  LSLProtocolAPI
  257.       mov   returnCode,ax     /* return code */
  258.       mov   retES,es          /* returned pointer */
  259.       mov   retSI,si
  260.       pop   si          /* restore C's registers */
  261.    }
  262.  
  263.    if  ( GMC_SUCCESS == returnCode ) {
  264.       /*
  265.          We got the module control API for this MLID or Protocol.
  266.          Call it with function 0 to retrieve the module's
  267.          configuration table.
  268.       */
  269.       ModuleAPI = (FuncPtr)MK_FP( retES, retSI );  /* make a ptr to their API */
  270.       ASM {
  271.          push  si             /* save C's registers */
  272.          xor   si,si
  273.          mov   es,si          /* zero out return value */
  274.          xor   bx,bx          /* func 0 is always Get Config Table */
  275.          mov   ax,whichOne    /* logical board # when calling MLIDs */
  276.          call  ModuleAPI
  277.          mov   retES,es       /* returned pointer */
  278.          mov   retSI,si
  279.          pop   si             /* restore C's registers */
  280.       }
  281.       *configTable = MK_FP( retES, retSI );
  282.    }  /* if we found the protocol or MLID */
  283.  
  284.    return ( returnCode );
  285. }  /* GetModuleConfig() */
  286.  
  287.  
  288. /*
  289.    GetMLIDConfig  returns a pointer to the configuration table
  290.                   for a given MLID.  Pass in the MLID number desired.
  291. */
  292. typedef struct {
  293.    char           Signature[ 26 ];     /* always "HardwareDriverMLID" */
  294.    unsigned char  ConfigTableMajorVer;
  295.    unsigned char  ConfigTableMinorVer;
  296.    unsigned char  NodeAddress[ 6 ];
  297.    unsigned int   ModeFlags;
  298.    unsigned int   BoardNumber;
  299.    unsigned int   BoardInstance;
  300.    unsigned int   MaxPacketSize;
  301.    unsigned int   BestDataSize;
  302.    unsigned int   WorstDataSize;
  303.    char far *     CardLongName;
  304.    char far *     CardShortName;
  305.    char far *     FrameString;
  306.    char           Reserved0[ 2 ];
  307.    unsigned int   FrameID;
  308.    unsigned int   TransportTime;
  309.    void far *     RouteHandler;
  310.    unsigned int   LookAheadSize;
  311.    unsigned int   LineSpeed;
  312.    unsigned int   QueueDepth;
  313.    char           Reserved1[ 6 ];
  314.    unsigned char  MLIDMajorVer;
  315.    unsigned char  MLIDMinorVer;
  316.    unsigned int   Flags;
  317.    unsigned int   SendRetries;
  318.    void far *     Link;
  319.    unsigned int   SharingFlags;
  320.    unsigned int   Slot;
  321.    unsigned int   IOAddress1;
  322.    unsigned int   IORange1;
  323.    unsigned int   IOAddress2;
  324.    unsigned int   IORange2;
  325.    unsigned long  MemoryAddress1;
  326.    unsigned int   MemorySize1;
  327.    unsigned long  MemoryAddress2;
  328.    unsigned int   MemorySize2;
  329.    unsigned char  IntLine1;
  330.    unsigned char  IntLine2;
  331.    unsigned char  DMALine1;
  332.    unsigned char  DMALine2;
  333. } MLIDConfigTable;
  334. typedef MLIDConfigTable far * MLIDPtr;
  335.  
  336. int GetMLIDConfig( int boardNumber, MLIDPtr * configPtr )
  337. {
  338.    return( GetModuleConfig( GET_MLID_CONTROL, boardNumber,
  339.       (DataPtr *)configPtr ) );
  340. }  /* GetMLIDConfig() */
  341.  
  342.  
  343. /*
  344.    GetProtocolConfig  returns a pointer to the configuration table
  345.                       for a given protocol.  Pass in the protocol
  346.                       number desired.
  347. */
  348. typedef struct {
  349.     unsigned char  ConfigTableMajorVer;
  350.     unsigned char  ConfigTableMinorVer;
  351.     char far *     ProtocolLongName;
  352.     char far *     ProtocolShortName;
  353.     unsigned char  ProtocolMajorVer;
  354.     unsigned char  ProtocolMinorVer;
  355.    char           ConfigTableReserved[ 16 ];
  356. } ProtocolConfigTable;
  357. typedef ProtocolConfigTable far * ProtocolPtr;
  358.  
  359. int GetProtocolConfig( int protoNumber, ProtocolPtr * configPtr )
  360. {
  361.    return( GetModuleConfig( GET_PROTOCOL_CONTROL, protoNumber,
  362.       (DataPtr *)configPtr ) );
  363. }  /* GetProtocolConfig() */
  364.  
  365.  
  366. /*
  367.    GetNetCfgPath  returns a copy of the full path where the
  368.                   NET.CFG file was loaded.
  369. */
  370. char * GetNetCfgPath( void )
  371. {
  372.    int retDS, retDX;
  373.    static char netCfgBuff[ 81 ] = "";
  374.    char far * netCfg;
  375.    int i;
  376.  
  377.    if  ( !DetectLSL() )
  378.       return ( NULL );
  379.  
  380.    ASM {
  381.       push  ds
  382.       mov   bx,0007h          /* Func 7: Get NET.CFG Path */
  383.       call  LSLGeneralAPI
  384.       mov   retDS,ds
  385.       mov   retDX,dx
  386.       pop   ds
  387.    }
  388.  
  389.    netCfg = MK_FP( retDS, retDX );
  390.  
  391.    /*
  392.       Have to copy this ourselves because we might be in
  393.       small model, so strcpy() won't handle the far *.
  394.    */
  395.    i = 0;
  396.    while ( 0 != ( netCfgBuff[ i ] = netCfg[ i ] ) )
  397.       i++;
  398.  
  399.    return ( netCfgBuff );
  400. }  /* GetNetCfgPath() */
  401.  
  402.  
  403. /* eof: VERODI.C */